package com.ridanlabs.professorwebsite.controller;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreFailureException;
import com.googlecode.objectify.Key;
import com.ridanlabs.professorwebsite.Util;
import com.ridanlabs.professorwebsite.models.Course;
import com.ridanlabs.professorwebsite.models.DAO;
import com.ridanlabs.professorwebsite.models.UserProfile;

@Controller
public class StudentController {
	private DAO dao = new DAO();
	private UserProfile user = Util.getAuthenticatedUser();
	
	@PreAuthorize("hasRole('STUDENT')")
	@RequestMapping(value="/student/index")
	public ModelAndView index() {
		ModelAndView mv = new ModelAndView("student/index");
		
		if( user.getCourses() != null && !user.getCourses().isEmpty() )  {
			Map<Key<Course>, Course> courses =  dao.ofy().get( user.getCourses() );
			mv.addObject("courses", courses);
			mv.addObject("courseCount", courses.size());
		} else {
			mv.addObject("courseCount", 0);
		}
		
    	mv.addObject("user", user);
    	
		return mv;
	}
	
	@PreAuthorize("hasRole('STUDENT')")
	@RequestMapping("/course/view/available")
	public ModelAndView courses() {
		ModelAndView mv = new ModelAndView("course/available");
		DAO dao = new DAO();
    	UserProfile user = Util.getAuthenticatedUser();
    	
    	List<Course> courses = dao.ofy().query(Course.class).limit(30).list(); //TODO: figure out a way to handle limit, since we dont wayyyyy too many results!
    	
    	if( !courses.isEmpty() ) {
    		mv.addObject("courses", courses);
    		mv.addObject("courseCount", courses.size());
    	} else {
    		mv.addObject("courseCount", 0);
    	}
    	
    	mv.addObject("user", user);
		
		return mv;
	}
	
	@PreAuthorize("hasRole('STUDENT')")
	@RequestMapping("/student/course/{id}/join")
	public String joinClass(@PathVariable("id") String id) {
		Course course = dao.findCourse(id);
		
		if(course == null) return "redirect:/student/index"; //no course of id found
		
		Key<Course> courseKey = course.getKey();
		for(Key<Course> key : user.getCourses()) {
			if( courseKey.compareTo(key) == 0 ) //if user already added this class/ dont add again ---just return
				return "redirect:/student/index";
		}
		
		course.addStudent(user.getKey());
		user.addCourse(course.getKey());
		
		dao.saveCourse( course );
		dao.saveUserProfile( user );
		
		return "redirect:/student/index";
	}
	
	@PreAuthorize("hasRole('STUDENT')")
	@RequestMapping("/student/course/{id}")
	public ModelAndView course(@PathVariable("id") String id) {
		BlobInfoFactory blobInfoFactory = new BlobInfoFactory();
		ModelAndView mv;
		
		Course course = dao.ofy().query(Course.class).filter("courseStudents", user).filter("id", id).get();
		
		if( course == null ) {
			mv = new ModelAndView("error");
			mv.addObject("errorMessage", "Course Not Found");
			return mv;
		}
		
		HashSet<BlobKey> courseNotesKeys = course.getNotes();
		LinkedList<BlobInfo> courseNotesInfos = new LinkedList<BlobInfo>();
		
		if( !courseNotesKeys.isEmpty() ) {
			for(BlobKey blobKey: courseNotesKeys) {
				courseNotesInfos.add( blobInfoFactory.loadBlobInfo(blobKey) );
			}
			
		} 
			
		mv = new ModelAndView("course/client");
		
		mv.addObject("numOfNotes", courseNotesKeys.size());
		mv.addObject("notesInfos", courseNotesInfos);
		mv.addObject("course", course);
		mv.addObject("user", user);
		
		return mv;
	}
}
